#include <opencv2/opencv.hpp>
#include <iostream>

using namespace cv;
using namespace std;

void detectAndDraw(Mat& img, Mat& img2, CascadeClassifier& cascade, double scale)
{
    int i = 0;
    double t = 0;
    vector<Rect> faces;
    const static Scalar colors[] =  { CV_RGB(0,0,255),
        CV_RGB(0,128,255),
        CV_RGB(0,255,255),
        CV_RGB(0,255,0),
        CV_RGB(255,128,0),
        CV_RGB(255,255,0),
        CV_RGB(255,0,0),
        CV_RGB(255,0,255)} ;
    Mat gray, smallImg( cvRound (img.rows/scale), cvRound(img.cols/scale), CV_8UC1 );
    Mat censor;
    cvtColor( img, gray, CV_BGR2GRAY );
    resize( gray, smallImg, smallImg.size(), 0, 0, INTER_LINEAR );
    equalizeHist( smallImg, smallImg );

    t = (double)cvGetTickCount();
    cascade.detectMultiScale( smallImg, faces,
        1.1, 2, 0
        //|CV_HAAR_FIND_BIGGEST_OBJECT
        //|CV_HAAR_DO_ROUGH_SEARCH
        |CV_HAAR_SCALE_IMAGE
        ,
        Size(30, 30) );
    t = (double)cvGetTickCount() - t;
    //printf( "detection time = %g ms\n", t/((double)cvGetTickFrequency()*1000.) );
    for( vector<Rect>::const_iterator r = faces.begin(); r != faces.end(); r++, i++ )
    {
        Scalar color = colors[i%8];
        //rectangle(img,*r,color,1,0,0);

        if(!faces.empty())
        {
            Mat roi(img,*r);
            resize(img2,censor,Size(roi.rows,roi.cols),0,0,INTER_NEAREST);
            roi += censor;
        }

    }
    imshow( "result", img );
}

int main(int argc, char *argv[])
{
    Mat frame;
    Mat smiley = imread("smiley.bmp",1);
    if(smiley.empty())
    {
        cout << "Error! Cant load smiley!";
        return -1;
    }
    VideoCapture cap(0);
    namedWindow("Frame");
    CascadeClassifier cascade;
    String cascadeName = "haarcascade_frontalface_alt.xml";
    cascade.load(cascadeName);
    while(true)
    {
        cap >> frame;
        imshow("Frame",frame);
        detectAndDraw(frame,smiley,cascade,1);
        if(waitKey(30) > 0) break;
    }

    return 0;
}
